package com.atgulimall.com.cart.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.TypeReference;
import com.atguigu.common.utils.R;
import com.atgulimall.com.cart.feign.ProductFeign;
import com.atgulimall.com.cart.intercept.CartInterceptor;
import com.atgulimall.com.cart.service.CartService;
import com.atgulimall.com.cart.vo.*;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.BoundHashOperations;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.stream.Collectors;

/**
 * @author 满超
 * @date 2020/06/20
 **/
@Service
public class CartServiceImpl implements CartService {

    @Autowired
    StringRedisTemplate redisTemplate;

    @Autowired
    ProductFeign productFeign;

    @Autowired
    ThreadPoolExecutor threadPoolExecutor;

    private final String CART_PREFIX = "gulimall:cart:";//前缀

    @Override
    public CartItem addToCart(Long skuId, Integer num) throws ExecutionException, InterruptedException {
        BoundHashOperations<String, Object, Object> cartOps = getCartOps();
        //商品添加到购物车
        CartItem cartItem = new CartItem();

        //gulimall:cart:userId redis查看购物车有没有商品
        String o = (String) cartOps.get(skuId.toString());
        if (StringUtils.isEmpty(o)){
            //购物车无商品
            //远程调用查询信息
            CompletableFuture<Void> skuInfoTask = CompletableFuture.runAsync(() -> {
                R info = productFeign.info(skuId);
                SkuInfoVo skuInfo = info.getData("skuInfo", new TypeReference<>() {
                });
                cartItem.setCheck(true);
                cartItem.setCount(num);
                cartItem.setSkuTitle(skuInfo.getSkuTitle());
                cartItem.setPrice(skuInfo.getPrice());
                cartItem.setImg(skuInfo.getSkuDefaultImg());
                cartItem.setSkuId(skuId);
            }, threadPoolExecutor);

            CompletableFuture<Void> getSaleAttr = CompletableFuture.runAsync(() -> {
                //远程查销售组合信息
                List<String> attrValues = productFeign.getAttrValues(skuId);
                cartItem.setSkuAttr(attrValues);

            }, threadPoolExecutor);

            CompletableFuture.allOf(skuInfoTask,getSaleAttr).get();

            String s = JSON.toJSONString(cartItem);//转为json字符串
            cartOps.put(skuId.toString(),s);

            return cartItem;

        } else {
            //购物车有数据修改数量
            CartItem item = JSON.parseObject(o, CartItem.class);
            item.setCount(item.getCount() + num);

            cartOps.put(skuId.toString(),JSON.toJSONString(item));
            return item;
        }
    }

    @Override
    public CartItem getCartItem(Long skuId) {
        BoundHashOperations<String, Object, Object> cartOps = getCartOps();
        String o = (String) cartOps.get(skuId.toString());

        return JSON.parseObject(o, CartItem.class);
    }

    @Override
    public Cart getCart() throws ExecutionException, InterruptedException {
        Cart cart = new Cart();
        UserInfoTo userInfoTo = CartInterceptor.threadLocal.get();
        if (userInfoTo.getUserId() != null){
            //登录
            String cartKey =CART_PREFIX + userInfoTo.getUserId();
            //临时购物车数据
            List<CartItem> tempCartItem = getCartItem(CART_PREFIX + userInfoTo.getUserKey());
            if (tempCartItem != null){
                //合并，添加进登录的购物车里面
                for (CartItem cartItem : tempCartItem) {
                    addToCart(cartItem.getSkuId(),cartItem.getCount());
                }
                //清除临时购物车数据
                clearCart(CART_PREFIX + userInfoTo.getUserKey());
            }

            //获取登录后的购物车,包含临时的
            List<CartItem> cartItem = getCartItem(cartKey);
            cart.setItems(cartItem);

        } else {
            //没登录，临时购物车
            String cartKey =CART_PREFIX + userInfoTo.getUserKey();
            List<CartItem> cartItem = getCartItem(cartKey);
            cart.setItems(cartItem);
        }
        return cart;
    }

    /**
     * 清空购物车
     * @param cartKey
     */
    @Override
    public void clearCart(String cartKey){
        redisTemplate.delete(cartKey);
    }

    @Override
    public void checkItem(Long skuId, Integer check) {
        BoundHashOperations<String, Object, Object> cartOps = getCartOps();
        CartItem cartItem = getCartItem(skuId);

        cartItem.setCheck(check == 1);
        String s = JSON.toJSONString(cartItem);
        cartOps.put(skuId.toString(),s);
    }

    @Override
    public void del(Long skuId) {
        BoundHashOperations<String, Object, Object> cartOps = getCartOps();
        cartOps.delete(skuId.toString());
    }

    @Override
    public void num(Long skuId, Integer num) {
        BoundHashOperations<String, Object, Object> cartOps = getCartOps();
        CartItem cartItem = getCartItem(skuId);
        cartItem.setCount(num);

        String s = JSON.toJSONString(cartItem);
        cartOps.put(skuId.toString(),s);
    }

    @Override
    public List<CartItem> getItem() {
        UserInfoTo userInfoTo = CartInterceptor.threadLocal.get();
        if (userInfoTo == null){
            return null;
        } else {
            String cartKey = CART_PREFIX + userInfoTo.getUserId();
            List<CartItem> cartItem = getCartItem(cartKey);

            return cartItem.stream().filter(CartItem::getCheck).map(item -> {
                item.setPrice(productFeign.getPrice(item.getSkuId()));
                return item;
            }).collect(Collectors.toList());
        }
    }

    /**
     * 获取购物车项
     * @param cartKey
     * @return
     */
    private List<CartItem> getCartItem(String cartKey){
        BoundHashOperations<String, Object, Object> cartOps = redisTemplate.boundHashOps(cartKey);
        List<Object> values = cartOps.values();
        if (values != null && values.size()>0) {
            return values.stream().map(o -> JSON.parseObject(o.toString(), CartItem.class)).collect(Collectors.toList());
        }
        return null;
    }

    /**
     * 根据登录状态，从redis获取要操作的购物车
     * @return
     */
    public BoundHashOperations<String, Object, Object> getCartOps() {
        UserInfoTo userInfoTo = CartInterceptor.threadLocal.get();
        //判断是登录的还是临时用户
        String cartKey = "";
        if (userInfoTo.getUserId() != null){
            //登陆了
            cartKey = CART_PREFIX + userInfoTo.getUserId();
        } else {
            cartKey = CART_PREFIX + userInfoTo.getUserKey();
        }

        return redisTemplate.boundHashOps(cartKey);
    }
}
